#ifndef _NET_IO_
#define _NET_IO_

#include "raknet\WindowsIncludes.h"
#include "..\Core\base.h"

#include "raknet\RakPeerInterface.h"
#include "raknet\BitStream.h"
#include "raknet\RakNetTypes.h"
#include "raknet\MessageIdentifiers.h"
#include "raknet\GetTime.h"
/*#include "raknet\Kbhit.h"
/*#include "raknet\PacketLogger.h"
#include "raknet\RakNetStatistics.h"*/
#include "raknet\RakSleep.h"

#include "PlayerDescriptor.h"

using namespace RakNet;

namespace air {
	struct NetMessage;
	/**
	 * @brief Network Communication
	 */
	class NetIO {
	public:
		NetIO();
		~NetIO();
		/**
		 * @brief get the player id by ip address
		 *
		 * @return player's id
		 */
		int findPlayerBySystemAddress(SystemAddress& sysAddr);
		/**
		 * @brief connect to server which manage all the rooms
		 */
		void ConnectToMainServer();
		/**
		 * @brief send message to main server
		 */
		void sendToMainServer(NetMessage*) {}
		/**
		 * @brief receive message from main server
		 */
		void recvFromMainServer() {}
		/**
		 * @brief start battle server will call startBattleServer. client will call ConnectToBattleServer
		 */
		void startBattle();
		/**
		 * @brief function for server to create a battle
		 */
		void StartBattleServer();
		/**
		 * @brief function for client to create a battle
		 */
		void ConnectToBattleServer();
		/**
		 * @brief battle-server-side function broadcast specified message.
		 *
		 * @param nMsg message to be broadcast
		 * @param playerId to be excluded from broadcast. playerId = -1 means all players
		 */
		void broadcastExcludePlayer(NetMessage* nMsg, int playerId);
		/**
		 * @brief battle-client-side function send message to battle-server
		 *
		 * @param nMsg message to be sent to battle-server
		 */
		void sendToBattleServer(NetMessage* nMsg);
		/**
		 * @brief receive message from battle
		 */
		void recv(Packet*);
		void Deallocate(Packet* p) { node->DeallocatePacket(p); }
		/**
		 * @brief test whether all information is ready to begin a battle
		 *
		 * @param bool true for yes, otherwise false
		 */
		bool ReadyBattle();
		/**
		 * @brief reset the netIO after ending a battle
		 */		 		
		void reset();
		 
		// Communication with BattleScene
		int getPlayerCount() { return expectedPlayerCount; }
		int getMeId() { return me; }
		PlayerDescriptor* getPlayerInfo(int* playerCount) 
		{
			*playerCount = expectedPlayerCount;
			return playerInfo; 
		}

		/**
		 * @brief interface to RakNet
		 */
		RakPeerInterface *node;		 
		/**
		 * @brief record total number of players in a game
		 */	
		int expectedPlayerCount;
		/**
		 * @brief record my id in a game
		 */
		int me;
		//TODO aircraft type
		/**
		 * @brief record whether this is a server
		 */
		bool server;
		PlayerDescriptor playerInfo[10];
	private:
		int readyCount;
	};
}

#endif